package com.example.jetpacktest.activity.material_design

import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.jetpacktest.R
import com.example.jetpacktest.adapter.DiffUtilTest002Adapter
import com.example.jetpacktest.domain.My1User
import java.util.*

class DiffUtilTest002Activity: AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_diff_util_test002)

        val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
        val btnChange: Button = findViewById(R.id.btn_change)

        val datas = mutableListOf<My1User>()
        for(i in 1..10){
            datas.add(My1User(i.toLong(), "name $i", i + 30))
        }
        val adapter = DiffUtilTest002Adapter(datas, this)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = adapter

        val newDatas = mutableListOf<My1User>()
        datas.forEach {
            //必须new新的user对象，如果2个列表是相同的user对象，一个改了之后，另外一个也跟着改了
            //使用DiffUtil比较差异的时候就不会有差异
            val user = My1User(it.id, it.name, it.age)
            newDatas.add(user)
        }
        val random = Random()
        btnChange.setOnClickListener {
            val index = random.nextInt(10) // 0---9
            val temp = "999__$index"
            newDatas[index].name = temp

            //adapter.notifyDataSetChanged()

            adapter.datas = newDatas
            val res = DiffUtil.calculateDiff(MyCallback(datas, newDatas), false)
            res.dispatchUpdatesTo(adapter)

            //保存更改，以便下次比较差异
            datas[index] = newDatas[index]
            
        }
    }


    class MyCallback(private val oldDatas: MutableList<My1User>, private val newDatas: MutableList<My1User>): DiffUtil.Callback(){

        companion object{
            val TAG: String = MyCallback::class.java.simpleName
        }

        override fun getOldListSize(): Int {
            return oldDatas.size
        }

        override fun getNewListSize(): Int {
            return newDatas.size
        }


        /**
         * 判断item对象是否相同，按照自己的业务逻辑来定义。
         * 如果使用java中判断对象是否相同的定义（根据地址判断），则2个列表中对象不同，因为地址不同
         * 此处使用的是根据对象的id来判断
         */
        override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val res = oldDatas[oldItemPosition].id == newDatas[newItemPosition].id
            Log.d(TAG, "areItemsTheSame()...res = $res..oldItemPosition = $oldItemPosition...newItemPosition = $newItemPosition" +
                    "...oldDatas[oldItemPosition].id = ${oldDatas[oldItemPosition].id}....newDatas[newItemPosition].id = ${newDatas[newItemPosition].id}")
            return res
        }

        /**
         * 判断对象的内容是否相同，对象相同（本例中判断依据为id相同），对象的内容未必相同
         */
        override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
            val oldUser = oldDatas[oldItemPosition]
            val newUser = newDatas[newItemPosition]
            val res = oldUser.name == newUser.name && oldUser.age == newUser.age
            Log.d(TAG, "areContentsTheSame()....res = $res....oldUser = $oldUser.....newUser = $newUser")
            return res
        }

        /**
         * 获取有效差异，实现局部刷新的关键点之1
         */
        override fun getChangePayload(oldItemPosition: Int, newItemPosition: Int): Any? {
            val oldUser = oldDatas[oldItemPosition]
            val newUser = newDatas[newItemPosition]
            Log.d(TAG, "getChangePayload()....oldItemPosition = $oldItemPosition......newItemPosition = $newItemPosition")
            Log.d(TAG, "getChangePayload()....oldUser = $oldUser......newUser = $newUser")
            val bundle = Bundle()
            if(oldUser.name != newUser.name){
                bundle.putString(DiffUtilTest002Adapter.KEY_NAME, newUser.name)
            }
            if(oldUser.age != newUser.age){
                bundle.putInt(DiffUtilTest002Adapter.KEY_AGE, newUser.age)
            }
            if(bundle.isEmpty){
                return null
            }
            return bundle
        }

    }

}